package com.weifei.core.mvc;

import com.weifei.core.anotation.WFRequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 主要完成请求传递到服务器的参数列表与method实参列表的对应关系
 */
public class WFHandlerAdapter {

    public WFHandlerAdapter() {}

    public boolean support(Object adapter) {
        return adapter instanceof WFHandlerMapping;
    }
    private Object castStringValue(String value, Class clazz) {
        if (clazz == String.class) {
            return value;
        } else if (clazz == Integer.class) {
            return Integer.valueOf(value);
        } else if (clazz == int.class) {
            return Integer.valueOf(value).intValue();
        } else {
            return null;
        }
    }
    public WFModelAndView handler(HttpServletRequest request, HttpServletResponse response, Object handler) throws InvocationTargetException, IllegalAccessException {
        WFHandlerMapping handlerMapping = (WFHandlerMapping) handler;
        //保存方法的参数列表
        Map<String, Integer> paramMapping = new HashMap<>();
        Annotation[][] pa = handlerMapping.getMethod().getParameterAnnotations();
        for (int i=0; i<pa.length; i++) {
            for (Annotation a : pa[i]) {
                if (a instanceof WFRequestParam) {
                    String paramName = ((WFRequestParam) a).value();
                    if (!"".equals(paramName)) {
                        paramMapping.put(paramName, i);
                    }
                }
            }
        }
        Class[] paramTypes = handlerMapping.getMethod().getParameterTypes();
        for (int i=0; i<paramTypes.length; i++) {
            Class type = paramTypes[i];
            if (type == HttpServletRequest.class || type == HttpServletResponse.class) {
                paramMapping.put(type.getName(), i);
            }
        }
        // 保存请求中的参数
        Map<String, String> requestParams = new HashMap<>();
        Enumeration<String> enumeration = request.getParameterNames();
        while (enumeration.hasMoreElements()) {
            String key = enumeration.nextElement();
            requestParams.put(key, request.getParameter(key));
        }

        Object[] paramValues = new Object[paramTypes.length];
        for (Map.Entry<String, String> entry : requestParams.entrySet()) {
            if (!paramMapping.containsKey(entry.getKey())) {
                continue;
            }
            int index = paramMapping.get(entry.getKey());
            paramValues[index] = this.castStringValue(entry.getValue()
                    , paramTypes[index]);
        }

        if (paramMapping.containsKey(HttpServletResponse.class.getName())) {
            int index = paramMapping.get(HttpServletResponse.class.getName());
            paramValues[index] = response;
        }
        if (paramMapping.containsKey(HttpServletRequest.class.getName())) {
            int index = paramMapping.get(HttpServletRequest.class.getName());
            paramValues[index] = request;
        }

        // 利用反射调用method
        Object result = handlerMapping.getMethod().invoke(handlerMapping.getController(), paramValues);

        if (result == null) {
            return null;
        }
        if (handlerMapping.getMethod().getReturnType() == WFModelAndView.class) {
            return (WFModelAndView) result;
        } else {
            return null;
        }
    }
}
